import sys
import os
import time
import logging
import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont

# 添加项目根目录到Python路径
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from face_recognition import FaceRecognition

def cv2_img_add_chinese_text(img, text, position, textColor=(0, 255, 0), textSize=30):
    """
    在OpenCV图像上添加中文文字
    """
    if isinstance(img, np.ndarray):
        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    
    # 创建一个可以在图像上绘制的对象
    draw = ImageDraw.Draw(img)
    
    # 尝试多个可能的字体路径
    font_paths = [
        "/System/Library/Fonts/PingFang.ttc",  # macOS
        "/System/Library/Fonts/STHeiti Light.ttc",  # macOS
        "/usr/share/fonts/truetype/droid/DroidSansFallbackFull.ttf",  # Linux
        "C:\\Windows\\Fonts\\simhei.ttf",  # Windows
        "Arial Unicode.ttf"  # 默认
    ]
    
    font = None
    for font_path in font_paths:
        try:
            font = ImageFont.truetype(font_path, textSize, encoding="utf-8")
            break
        except:
            continue
    
    if font is None:
        # 如果没有找到合适的字体，使用默认字体
        font = ImageFont.load_default()
    
    # 绘制文字
    draw.text(position, text, textColor, font=font)
    
    # 转换回OpenCV格式
    return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)

def check_face_quality(gray_face):
    """
    检查人脸图像质量
    """
    # 检查亮度
    mean_brightness = np.mean(gray_face)
    if mean_brightness < 30 or mean_brightness > 230:
        return False
        
    # 检查对比度
    contrast = np.std(gray_face)
    if contrast < 20:
        return False
        
    # 检查图像大小
    if gray_face.shape[0] < 60 or gray_face.shape[1] < 60:
        return False
    
    return True

def continuous_face_recognition(interval=3, max_time=None, show_window=True):
    """
    持续进行人脸识别，可选择是否显示摄像头窗口
    """
    # 设置日志
    logging.basicConfig(level=logging.INFO)
    
    # 初始化识别器，调整参数使检测更严格
    custom_config = {
        'min_neighbors': 5,  # 增加此值使检测更严格
        'scale_factor': 1.1,  # 增加此值减少误检
        'recognition_threshold': 30,  # 提高识别阈值
        'min_face_size': (80, 80)  # 增加最小人脸尺寸
    }
    
    recognizer = FaceRecognition(custom_config)
    
    print(f"开始连续人脸识别，每 {interval} 秒识别一次...")
    print("按 'q' 键或 Ctrl+C 停止识别")
    
    start_time = time.time()
    recognition_count = 0
    last_result_text = "等待识别..."
    
    try:
        # 打开摄像头
        cap = cv2.VideoCapture(0)
        if not cap.isOpened():
            print("无法打开摄像头，请检查设备")
            return 0
            
        last_recognition_time = 0
        
        while True:
            # 如果设置了最大时间，检查是否已超时
            if max_time and (time.time() - start_time) > max_time:
                print(f"\n已达到最大运行时间 {max_time} 秒，停止识别")
                break
                
            # 读取一帧
            ret, frame = cap.read()
            if not ret:
                print("无法获取图像帧")
                break
            
            # 图像预处理
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            gray = cv2.equalizeHist(gray)
            
            # 人脸检测
            faces = recognizer.face_cascade.detectMultiScale(
                gray,
                scaleFactor=recognizer.config['scale_factor'],
                minNeighbors=recognizer.config['min_neighbors'],
                minSize=recognizer.config['min_face_size']
            )
            
            # 显示倒计时
            time_to_next = max(0, interval - (time.time() - last_recognition_time))
            frame = cv2_img_add_chinese_text(frame, 
                                           f"下次识别: {time_to_next:.1f}秒", 
                                           (10, 30),
                                           textColor=(0, 0, 255),
                                           textSize=30)
            
            # 定时识别
            if (time.time() - last_recognition_time) >= interval:
                print(f"\n第 {recognition_count + 1} 次识别...")
                
                valid_faces = []
                for (x, y, w, h) in faces:
                    face_roi = gray[y:y+h, x:x+w]
                    if check_face_quality(face_roi):
                        valid_faces.append((x, y, w, h))
                        cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
                
                if len(valid_faces) == 0:
                    last_result_text = "没有人"
                    print(f"结果: {last_result_text}")
                else:
                    # 对每个有效的人脸进行识别
                    result = None
                    max_confidence = 0
                    
                    for (x, y, w, h) in valid_faces:
                        face_roi = frame[y:y+h, x:x+w]
                        current_result = recognizer.recognize_face(face_roi)
                        
                        if current_result and current_result['confidence'] > max_confidence:
                            result = current_result
                            max_confidence = current_result['confidence']
                    
                    if result:
                        last_result_text = f"{result['person_name']} ({result['confidence']:.2f}%)"
                        print(f"结果: {result['person_name']} (置信度: {result['confidence']:.2f}%)")
                        
                        x, y, w, h = result['position']
                        cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 3)
                        frame = cv2_img_add_chinese_text(frame,
                                                       result['person_name'],
                                                       (x, y-30),
                                                       textColor=(0, 255, 0),
                                                       textSize=30)
                    else:
                        last_result_text = "陌生人"
                        print(f"结果: {last_result_text}")
                
                last_recognition_time = time.time()
                recognition_count += 1
            
            # 显示最后一次识别结果
            frame = cv2_img_add_chinese_text(frame,
                                           f"识别结果: {last_result_text}",
                                           (10, 60),
                                           textColor=(0, 0, 255),
                                           textSize=30)
            
            # 显示使用说明
            frame = cv2_img_add_chinese_text(frame,
                                           "按 'q' 退出",
                                           (10, frame.shape[0] - 30),
                                           textColor=(255, 255, 255),
                                           textSize=30)
            
            # 显示窗口
            if show_window:
                cv2.imshow('人脸识别监测', frame)
                if cv2.waitKey(1) & 0xFF == ord('q'):
                    print("\n用户按下q键，停止识别")
                    break
            else:
                time.sleep(0.05)
            
    except KeyboardInterrupt:
        print("\n用户中断，停止识别")
    finally:
        if 'cap' in locals() and cap.isOpened():
            cap.release()
        cv2.destroyAllWindows()
    
    print(f"共进行了 {recognition_count} 次识别")
    return recognition_count

def main():
    """
    程序入口函数，处理异常情况
    """
    try:
        # 默认每3秒识别一次，显示摄像头窗口
        continuous_face_recognition(interval=3, show_window=True)
    except Exception as e:
        print(f"发生错误: {e}")
        logging.exception("程序异常")

if __name__ == "__main__":
    main() 